package middleware

import (
	"github.com/go-playground/locales/en"
	"github.com/go-playground/locales/zh"
	ut "github.com/go-playground/universal-translator"
	"github.com/go-playground/validator/v10"
	"github.com/zeromicro/go-zero/core/logx"
	"gozero-demo/internal/constants"
	"gozero-demo/internal/types"
	"reflect"
	"regexp"
	"strings"
)

// 全局通用翻译器
var (
	uni      *ut.UniversalTranslator
	trans    ut.Translator
	validate *validator.Validate
)

func init() {
	// 初始化中文和英文翻译器
	zhLocale := zh.New()
	enLocale := en.New()
	uni = ut.New(zhLocale, enLocale)
	//var found bool
	//trans, found = uni.GetTranslator("zh")
	trans, _ = uni.GetTranslator("zh")

	//if !found {
	//	logx.Errorf("Failed to get Chinese translator, found: %v, trans: %v", found, trans)
	//}
	// 初始化验证器
	validate = validator.New()
	// 关键配置：注册标签名函数  可以配置字段中文名
	validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
		// 优先返回 label 标签内容
		if label := fld.Tag.Get("label"); label != "" {
			return label
		}
		// 次选返回 json 标签
		return fld.Tag.Get("json")
	})
	// 注册自定义验证器
	registerCustomTranslations(validate, trans)
	// 注册自定义规则
	validate.RegisterValidation("startswith", validateStartsWith)
	// 注册自定义规则 ^[a-zA-Z0-9\s\p{Han}]+$ 匹配特殊字符
	validate.RegisterValidation("no_special_chars", containsNoSpecialCharacters)
	// 注册自定义规则 ^\d+(\.\d{2})?$ 匹配金额的限制1000.00格式
	validate.RegisterValidation("numeric_decimal", isNumericDecimal)
}

// 自定义以指定字符开头的验证规则
func validateStartsWith(fl validator.FieldLevel) bool {
	field := fl.Field().String()
	param := fl.Param()
	return len(field) > 0 && strings.HasPrefix(field, param)
}

func containsNoSpecialCharacters(fl validator.FieldLevel) bool {
	specialCharRegex := regexp.MustCompile(`^[a-zA-Z0-9\s\p{Han}]+$`)
	return specialCharRegex.MatchString(fl.Field().String())
}

func isNumericDecimal(fl validator.FieldLevel) bool {
	specialCharRegex := regexp.MustCompile(`^\d+(\.\d{2})?$`)
	return specialCharRegex.MatchString(fl.Field().String())
}

// 注册自定义翻译
func registerCustomTranslations(validate *validator.Validate, trans ut.Translator) {
	// 注册自定义验证器
	validate.RegisterTranslation("required", trans, func(ut ut.Translator) error {
		return ut.Add("required", "{0} 是必填字段", true)
	}, func(ut ut.Translator, fe validator.FieldError) string {
		t, _ := ut.T("required", fe.Field())
		return t
	})

	validate.RegisterTranslation("min", trans, func(ut ut.Translator) error {
		return ut.Add("min", "{0} 最小值为 {1}", true)
	}, func(ut ut.Translator, fe validator.FieldError) string {
		t, _ := ut.T("min", fe.Field(), fe.Param())
		return t
	})

	validate.RegisterTranslation("oneof", trans, func(ut ut.Translator) error {
		return ut.Add("oneof", "{0} 必须是 {1} 中的一个", true)
	}, func(ut ut.Translator, fe validator.FieldError) string {
		t, _ := ut.T("oneof", fe.Field(), fe.Param())
		return t
	})

	validate.RegisterTranslation("gt", trans, func(ut ut.Translator) error {
		return ut.Add("gt", "{0} 必须大于 {1}", true)
	}, func(ut ut.Translator, fe validator.FieldError) string {
		t, _ := ut.T("gt", fe.Field(), fe.Param())
		return t
	})

	validate.RegisterTranslation("max", trans, func(ut ut.Translator) error {
		return ut.Add("max", "{0} 最大值为 {1}", true)
	}, func(ut ut.Translator, fe validator.FieldError) string {
		t, _ := ut.T("max", fe.Field(), fe.Param())
		return t
	})

	validate.RegisterTranslation("email", trans, func(ut ut.Translator) error {
		return ut.Add("email", "{0} 必须是有效的电子邮件地址", true)
	}, func(ut ut.Translator, fe validator.FieldError) string {
		t, _ := ut.T("email", fe.Field())
		return t
	})

	validate.RegisterTranslation("datetime", trans, func(ut ut.Translator) error {
		return ut.Add("datetime", "{0} 必须是有效的日期时间格式 {1}", true)
	}, func(ut ut.Translator, fe validator.FieldError) string {
		t, _ := ut.T("datetime", fe.Field(), fe.Param())
		return t
	})

	// 新增 numeric 规则的翻译
	validate.RegisterTranslation("numeric", trans, func(ut ut.Translator) error {
		return ut.Add("numeric", "{0} 必需是纯数字", true)
	}, func(ut ut.Translator, fe validator.FieldError) string {
		t, _ := ut.T("numeric", fe.Field())
		return t
	})

	// 处理类型不匹配的错误
	validate.RegisterTranslation("type_mismatch", trans, func(ut ut.Translator) error {
		return ut.Add("type_mismatch", "{0} 必须是 {1} 类型", true)
	}, func(ut ut.Translator, fe validator.FieldError) string {
		var targetType string
		switch fe.Type().Kind() {
		case 0:
			targetType = "int64"
		// 可以根据需要添加更多类型的判断
		default:
			targetType = fe.Type().Kind().String()
		}
		t, _ := ut.T("type_mismatch", fe.Field(), targetType)
		return t
	})

	// 注册 startsWith 规则的翻译
	validate.RegisterTranslation("startswith", trans, func(ut ut.Translator) error {
		return ut.Add("startswith", "{0} 必须以 {1} 开头", true)
	}, func(ut ut.Translator, fe validator.FieldError) string {
		t, _ := ut.T("startswith", fe.Field(), fe.Param())
		return t
	})

	// 注册 gtfield 规则的翻译
	validate.RegisterTranslation("gtfield", trans, func(ut ut.Translator) error {
		return ut.Add("gtfield", "{0} 必须晚于 {1}", true)
	}, func(ut ut.Translator, fe validator.FieldError) string {
		t, _ := ut.T("gtfield", fe.Field(), fe.Param())
		return t
	})

	// 注册 no_special_characters 规则的翻译
	validate.RegisterTranslation("no_special_chars", trans, func(ut ut.Translator) error {
		return ut.Add("no_special_chars", "{0} 不能包含特殊字符", true)
	}, func(ut ut.Translator, fe validator.FieldError) string {
		t, _ := ut.T("no_special_chars", fe.Field())
		return t
	})

	// 注册 numeric_decimal 规则的翻译
	validate.RegisterTranslation("numeric_decimal", trans, func(ut ut.Translator) error {
		return ut.Add("numeric_decimal", "{0} 必须是类似 10.00 的格式", true)
	}, func(ut ut.Translator, fe validator.FieldError) string {
		t, _ := ut.T("numeric_decimal", fe.Field())
		return t
	})

	// 注册 required_with 规则的翻译
	validate.RegisterTranslation("required_with", trans, func(ut ut.Translator) error {
		return ut.Add("required_with", "{0} 在 {1} 存在时是必填字段", true)
	}, func(ut ut.Translator, fe validator.FieldError) string {
		t, _ := ut.T("required_with", fe.Field(), fe.Param())
		return t
	})

}

// 处理验证错误
func handleValidationErrors(err validator.ValidationErrors) string {
	var errorMessages []string
	for _, e := range err {
		errorMessages = append(errorMessages, e.Translate(trans))
	}
	return strings.Join(errorMessages, ", ")
}

// ValidateRequest 验证请求参数
func ValidateRequest(req interface{}) error {
	if err := validate.Struct(req); err != nil {
		if _, ok := err.(*validator.InvalidValidationError); ok {
			logx.Errorf("Invalid validation error: %v", err)
			return types.NewMyError(constants.CodeParamsValidationFail.Code, constants.CodeParamsValidationFail.Msg+": 验证器配置错误")
		}
		errMessages := handleValidationErrors(err.(validator.ValidationErrors))
		return types.NewMyError(constants.CodeParamsValidationFail.Code, errMessages)
	}
	return nil
}
